package config

import (
	"gitee.com/huangxinbo/xcas/pkg"
	"github.com/gin-gonic/gin"
)

type Config struct {
	Server *ServerConfig
	DB     *DBConfig
	Redis  *RedisConfig
	Log    *LogConfig
	Mail   *MailConfig
	JWT    *JWTConfig
	Upload *UploadConfig
	OAuth  *OAuthConfig
	Asynq  *AsynqConfig
}

type ServerConfig struct {
	Port        int
	Mode        string // test or debug or release
	Name        string
	Version     string
	Description string
	URL         string
	BasePath    string
}

type DBConfig struct {
	Driver          string
	DSN             string
	MaxIdleConns    int
	MaxOpenConns    int
	ConnMaxIdleTime int
	ConnMaxLifetime int
	EnableSQLLog    bool // 控制是否记录 SQL 语句
}

type RedisConfig struct {
	Addr     string
	Password string
	Username string
	DB       int
}

type LogConfig struct {
	Level      string
	Path       string
	MaxSize    int
	MaxBackups int
	MaxAge     int
}

type MailConfig struct {
	TemplatesPath string
	Host          string
	Port          int
	Username      string
	Password      string
	From          string
}

type JWTConfig struct {
	Secret    string
	Issuer    string
	ExpiresAt int
}

type AsynqConfig struct {
	DB          int
	Concurrency int
	Critical    int
	Default     int
	Low         int
}

type UploadConfig struct {
	MaxSize     int
	StorageType string
	LocalPath   string

	// Aliyun OSS Configuration
	AliyunEndpoint        string
	AliyunAccessKeyID     string
	AliyunAccessKeySecret string
	AliyunBucketName      string

	// Huawei OBS Configuration
	HuaweiEndpoint        string
	HuaweiAccessKeyID     string
	HuaweiAccessKeySecret string
	HuaweiBucketName      string

	// Tencent COS Configuration
	TencentEndpoint   string
	TencentSecretID   string
	TencentSecretKey  string
	TencentBucketName string

	// Baidu BOS Configuration
	BaiduEndpoint        string
	BaiduAccessKeyID     string
	BaiduAccessKeySecret string
	BaiduBucketName      string

	// AWS S3 Configuration
	AWSRegion          string
	AWSAccessKeyID     string
	AWSSecretAccessKey string
	AWSBucketName      string

	// Azure Blob Storage Configuration
	AzureAccountName   string
	AzureAccountKey    string
	AzureContainerName string

	// Qiniu Kodo Configuration
	QiniuEndpoint   string
	QiniuAccessKey  string
	QiniuSecretKey  string
	QiniuBucketName string

	// Google Cloud Storage Configuration
	GoogleProjectID       string
	GoogleBucketName      string
	GoogleCredentialsFile string

	// MinIO Configuration
	MinIOEndpoint   string
	MinIOAccessKey  string
	MinIOSecretKey  string
	MinIOBucketName string
	MinIOUseSSL     bool
}

// OAuthConfig OAuth 配置
type OAuthConfig struct {
	GitHub *OAuthProviderConfig
	Gitee  *OAuthProviderConfig
}

// OAuthProviderConfig OAuth 提供商配置
type OAuthProviderConfig struct {
	ClientID     string
	ClientSecret string
}

func InitConfig() *Config {
	// 先创建 ServerConfig 用于判断模式
	serverConfig := &ServerConfig{
		Name:        pkg.GetEnvString("SERVER.NAME", "XCAS"),
		Version:     pkg.GetEnvString("SERVER.VERSION", "1.0.0"),
		Description: pkg.GetEnvString("SERVER.DESCRIPTION", "XCAS is a cas server"),
		Port:        pkg.GetEnvInt("SERVER.PORT", 8080),
		Mode:        pkg.GetEnvString("SERVER.MODE", gin.ReleaseMode),
		BasePath:    pkg.GetEnvString("SERVER.BASEPATH", "/"),
		URL:         pkg.GetEnvString("SERVER.URL", ""),
	}

	return &Config{
		Server: serverConfig,
		DB: &DBConfig{
			Driver:          pkg.GetEnvString("DB.DRIVER", "postgres"),
			DSN:             pkg.GetEnvString("DB.DSN", ""),
			MaxIdleConns:    pkg.GetEnvInt("DB.MAXIDLECONNS", 10),
			MaxOpenConns:    pkg.GetEnvInt("DB.MAXOPENCONNS", 100),
			ConnMaxIdleTime: pkg.GetEnvInt("DB.CONNMAXIDLETIME", 5),
			ConnMaxLifetime: pkg.GetEnvInt("DB.CONNMAXLIFETIME", 30),
			EnableSQLLog:    serverConfig.Mode != gin.ReleaseMode,
		},
		Redis: &RedisConfig{
			Addr:     pkg.GetEnvString("REDIS.ADDR", "localhost:6379"),
			Username: pkg.GetEnvString("REDIS.USERNAME", "default"),
			Password: pkg.GetEnvString("REDIS.PASSWORD", ""),
			DB:       pkg.GetEnvInt("REDIS.DB", 0),
		},
		Asynq: &AsynqConfig{
			DB:          pkg.GetEnvInt("ASYNQ.DB", 1),
			Concurrency: pkg.GetEnvInt("ASYNQ.CONCURRENCY", 10),
			Critical:    pkg.GetEnvInt("ASYNQ.CRITICAL", 6),
			Default:     pkg.GetEnvInt("ASYNQ.DEFAULT", 3),
			Low:         pkg.GetEnvInt("ASYNQ.LOW", 1),
		},
		Log: &LogConfig{
			Level:      pkg.GetEnvString("LOG.LEVEL", "info"),
			Path:       pkg.GetEnvString("LOG.PATH", "logs/"),
			MaxSize:    pkg.GetEnvInt("LOG.MAXSIZE", 50),
			MaxBackups: pkg.GetEnvInt("LOG.MAXBACKUPS", 30),
			MaxAge:     pkg.GetEnvInt("LOG.MAXAGE", 30),
		},
		Mail: &MailConfig{
			TemplatesPath: pkg.GetEnvString("MAIL.TEMPLATES.PATH", "mail_templates"),
			Host:          pkg.GetEnvString("MAIL.HOST", ""),
			Port:          pkg.GetEnvInt("MAIL.PORT", 587),
			Username:      pkg.GetEnvString("MAIL.USERNAME", ""),
			Password:      pkg.GetEnvString("MAIL.PASSWORD", ""),
			From:          pkg.GetEnvString("MAIL.FROM", ""),
		},
		JWT: &JWTConfig{
			Secret:    pkg.GetEnvString("JWT.SECRET", "xcas"),
			Issuer:    pkg.GetEnvString("JWT.ISS", "xcas"),
			ExpiresAt: pkg.GetEnvInt("JWT.EXPIRES_AT", 1),
		},
		Upload: &UploadConfig{
			MaxSize:     pkg.GetEnvInt("UPLOAD.MAX_SIZE", 10),
			StorageType: pkg.GetEnvString("UPLOAD.STORAGE_TYPE", "local"),
			LocalPath:   pkg.GetEnvString("UPLOAD.LOCAL_PATH", "uploads"),

			// Aliyun OSS Configuration
			AliyunEndpoint:        pkg.GetEnvString("UPLOAD.ALIYUN_ENDPOINT", ""),
			AliyunAccessKeyID:     pkg.GetEnvString("UPLOAD.ALIYUN_ACCESS_KEY_ID", ""),
			AliyunAccessKeySecret: pkg.GetEnvString("UPLOAD.ALIYUN_ACCESS_KEY_SECRET", ""),
			AliyunBucketName:      pkg.GetEnvString("UPLOAD.ALIYUN_BUCKET_NAME", ""),

			// Huawei OBS Configuration
			HuaweiEndpoint:        pkg.GetEnvString("UPLOAD.HUAWEI_ENDPOINT", ""),
			HuaweiAccessKeyID:     pkg.GetEnvString("UPLOAD.HUAWEI_ACCESS_KEY_ID", ""),
			HuaweiAccessKeySecret: pkg.GetEnvString("UPLOAD.HUAWEI_ACCESS_KEY_SECRET", ""),
			HuaweiBucketName:      pkg.GetEnvString("UPLOAD.HUAWEI_BUCKET_NAME", ""),

			// Tencent COS Configuration
			TencentEndpoint:   pkg.GetEnvString("UPLOAD.TENCENT_ENDPOINT", ""),
			TencentSecretID:   pkg.GetEnvString("UPLOAD.TENCENT_SECRET_ID", ""),
			TencentSecretKey:  pkg.GetEnvString("UPLOAD.TENCENT_SECRET_KEY", ""),
			TencentBucketName: pkg.GetEnvString("UPLOAD.TENCENT_BUCKET_NAME", ""),

			// Baidu BOS Configuration
			BaiduEndpoint:        pkg.GetEnvString("UPLOAD.BAIDU_ENDPOINT", ""),
			BaiduAccessKeyID:     pkg.GetEnvString("UPLOAD.BAIDU_ACCESS_KEY_ID", ""),
			BaiduAccessKeySecret: pkg.GetEnvString("UPLOAD.BAIDU_ACCESS_KEY_SECRET", ""),
			BaiduBucketName:      pkg.GetEnvString("UPLOAD.BAIDU_BUCKET_NAME", ""),

			// AWS S3 Configuration
			AWSRegion:          pkg.GetEnvString("UPLOAD.AWS_REGION", ""),
			AWSAccessKeyID:     pkg.GetEnvString("UPLOAD.AWS_ACCESS_KEY_ID", ""),
			AWSSecretAccessKey: pkg.GetEnvString("UPLOAD.AWS_SECRET_ACCESS_KEY", ""),
			AWSBucketName:      pkg.GetEnvString("UPLOAD.AWS_BUCKET_NAME", ""),

			// Azure Blob Storage Configuration
			AzureAccountName:   pkg.GetEnvString("UPLOAD.AZURE_ACCOUNT_NAME", ""),
			AzureAccountKey:    pkg.GetEnvString("UPLOAD.AZURE_ACCOUNT_KEY", ""),
			AzureContainerName: pkg.GetEnvString("UPLOAD.AZURE_CONTAINER_NAME", ""),

			// Qiniu Kodo Configuration
			QiniuEndpoint:   pkg.GetEnvString("UPLOAD.QINIU_ENDPOINT", ""),
			QiniuAccessKey:  pkg.GetEnvString("UPLOAD.QINIU_ACCESS_KEY", ""),
			QiniuSecretKey:  pkg.GetEnvString("UPLOAD.QINIU_SECRET_KEY", ""),
			QiniuBucketName: pkg.GetEnvString("UPLOAD.QINIU_BUCKET_NAME", ""),

			// Google Cloud Storage Configuration
			GoogleProjectID:       pkg.GetEnvString("UPLOAD.GOOGLE_PROJECT_ID", ""),
			GoogleBucketName:      pkg.GetEnvString("UPLOAD.GOOGLE_BUCKET_NAME", ""),
			GoogleCredentialsFile: pkg.GetEnvString("UPLOAD.GOOGLE_CREDENTIALS_FILE", ""),

			// MinIO Configuration
			MinIOEndpoint:   pkg.GetEnvString("UPLOAD.MINIO_ENDPOINT", ""),
			MinIOAccessKey:  pkg.GetEnvString("UPLOAD.MINIO_ACCESS_KEY", ""),
			MinIOSecretKey:  pkg.GetEnvString("UPLOAD.MINIO_SECRET_KEY", ""),
			MinIOBucketName: pkg.GetEnvString("UPLOAD.MINIO_BUCKET_NAME", ""),
			MinIOUseSSL:     pkg.GetEnvBool("UPLOAD.MINIO_USE_SSL", false),
		},
		OAuth: &OAuthConfig{
			GitHub: &OAuthProviderConfig{
				ClientID:     pkg.GetEnvString("OAUTH.GITHUB.CLIENT_ID", ""),
				ClientSecret: pkg.GetEnvString("OAUTH.GITHUB.CLIENT_SECRET", ""),
			},
			Gitee: &OAuthProviderConfig{
				ClientID:     pkg.GetEnvString("OAUTH.GITEE.CLIENT_ID", ""),
				ClientSecret: pkg.GetEnvString("OAUTH.GITEE.CLIENT_SECRET", ""),
			},
		},
	}
}
